import 'package:flutter/material.dart';
import 'dart:math' as math;

class ScrollableSelectorConfig {
  static const double defaultSelectedScale = 1.3;
  static const double defaultItemSpacing = 10.0;
  static const Duration animationDuration = Duration(milliseconds: 200);
  static const Duration scrollDuration = Duration(milliseconds: 300);
}

class ScrollableSelector extends StatefulWidget {
  final int itemCount;
  final double itemWidth;
  final Function(int) onSelected;

  const ScrollableSelector({
    Key? key,
    required this.itemCount,
    required this.itemWidth,
    required this.onSelected,
  }) : super(key: key);

  @override
  State<ScrollableSelector> createState() => _ScrollableSelectorState();
}

class _ScrollableSelectorState extends State<ScrollableSelector> {
  late PageController _pageController;
  int _selectedIndex = 0;
  final double _selectedScale = ScrollableSelectorConfig.defaultSelectedScale;
  final double _itemSpacing = ScrollableSelectorConfig.defaultItemSpacing;
  double? _currentViewportFraction;
  double? _lastMaxWidth;

  @override
  void initState() {
    super.initState();
    _selectedIndex = 0;
    _pageController = PageController(
      initialPage: 0,
      viewportFraction: _calculateViewportFraction(null),
    );
  }

  double _calculateViewportFraction(double? maxWidth) {
    if (maxWidth == null) return 1.0;
    return (widget.itemWidth + _itemSpacing) / maxWidth;
  }

  void _updatePageController(double viewportFraction) {
    if (_currentViewportFraction != viewportFraction) {
      final oldController = _pageController;
      _currentViewportFraction = viewportFraction;

      _pageController = PageController(
        initialPage: _selectedIndex,
        viewportFraction: viewportFraction,
      );

      Future.microtask(() {
        oldController.dispose();
      });
    }
  }

  void _handleItemCountChange() {
    if (_selectedIndex >= widget.itemCount) {
      setState(() {
        _selectedIndex = math.max(0, widget.itemCount - 1);
      });
      _pageController.animateToPage(
        _selectedIndex,
        duration: ScrollableSelectorConfig.scrollDuration,
        curve: Curves.easeOut,
      );
    }
  }

  @override
  void didUpdateWidget(ScrollableSelector oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.itemCount != oldWidget.itemCount) {
      _handleItemCountChange();
    }
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        if (_lastMaxWidth != constraints.maxWidth) {
          _lastMaxWidth = constraints.maxWidth;
          double viewportFraction = _calculateViewportFraction(constraints.maxWidth);

          WidgetsBinding.instance.addPostFrameCallback((_) {
            _updatePageController(viewportFraction);
          });
        }

        double scaledHeight = widget.itemWidth * _selectedScale;
        double containerHeight = scaledHeight;

        // 计算需要的额外页数来确保最后一个item可以滑动到最左边
        int extraPages = ((constraints.maxWidth - widget.itemWidth) /
            (widget.itemWidth + _itemSpacing))
            .ceil();

        return SizedBox(
          height: containerHeight,
          child: PageView.builder(
            controller: _pageController,
            onPageChanged: (index) {
              if (index < widget.itemCount) {
                setState(() {
                  _selectedIndex = index;
                });
                try {
                  widget.onSelected(index);
                } catch (e) {
                  debugPrint('Error in onSelected callback: $e');
                }
              }
            },
            itemCount: widget.itemCount + extraPages - 1, // 恢复额外页数
            pageSnapping: true,
            padEnds: false,
            physics: const BouncingScrollPhysics(),
            itemBuilder: (context, index) {
              // 如果超出实际item数量，返回空白占位
              if (index >= widget.itemCount) {
                return SizedBox(width: widget.itemWidth);
              }

              bool isSelected = _selectedIndex == index;
              bool isLastItem = index == widget.itemCount - 1;

              return Padding(
                padding: EdgeInsets.only(
                  left: index == 0 ? 0 : _itemSpacing / 2,
                  right: isLastItem
                      ? _itemSpacing / 2  // 修改最后一项的右边距
                      : _itemSpacing / 2,
                ),
                child: Container(
                  height: containerHeight,
                  alignment: Alignment.topCenter,
                  child: AnimatedScale(
                    scale: isSelected ? _selectedScale : 1.0,
                    duration: ScrollableSelectorConfig.animationDuration,
                    alignment: Alignment.topCenter,
                    child: Container(
                      width: widget.itemWidth,
                      height: widget.itemWidth,
                      decoration: BoxDecoration(
                        color: isSelected ? Colors.green : Colors.grey[800],
                        borderRadius: BorderRadius.circular(8),
                        border: Border.all(
                          color: isSelected
                              ? Colors.green[300]!
                              : Colors.transparent,
                          width: 2,
                        ),
                      ),
                      child: Center(
                        child: Text(
                          '${index + 1}',
                          style: TextStyle(
                            color: isSelected ? Colors.white : Colors.grey[400],
                            fontSize: isSelected ? 18 : 16,
                            fontWeight: isSelected
                                ? FontWeight.bold
                                : FontWeight.normal,
                          ),
                        ),
                      ),
                    ),
                  ),
                ),
              );
            },
          ),
        );
      },
    );
  }

  @override
  void dispose() {
    _pageController.dispose();
    super.dispose();
  }
}
